/*
	rlidstone 160311
	
	future:
		allow background image for the grid so that parts of the image are displayed on the tiles
		matrix 'drip' animator
*/


(function($)
{
	$.fn.spinner = function(options) 
	{
		var o = 
		{
			//width: 100,											// width of the containing div
			tileWidth: 10,
			//rowHeight: 6,										// (roughly, but not really?) the height of the row in pixels // TODO: look into fixing  to true pixel heights
			tileHeight: 6,										// (roughly, but not really?) the height of the row in pixels // TODO: look into fixing  to true pixel heights
        	gridWidth: 10,										// number of squares wide
        	gridHeight: 3,										// number of squares high
        	maxOpacity: 0.3,									// the maximum opacity that the squares should be allowed to go 
        	minOpacity: 0,
        	refreshRate: 50, 									// the number of milliseconds between refreshes (lower is faster)
        	duration: 400,										// animation duration
        	background: 'none',
        	backgroundColour: '#00f',
        	initialiser: 'none',
        	animator: 'faderandom',
        	dontStart: false
		};

		
		options && $.extend(o, options);
		
		
		/*
			initialiser collection
		*/
		var initialisers = 
		{
			none: function(block)
			{
				return block.css({ opacity: 0, 'background-color':o.backgroundColour  });
			},
			
			random: function(block, options)
			{
				options && $.extend(o, options);
				return block.css({ opacity: (Math.random() * o.maxOpacity), 'background-color':o.backgroundColour });
			}
		}
		
		
		
		/*
			animator collection
		*/
		var animators =
		{
			faderandom: function()
			{
				this.cell[Math.floor(Math.random() * this.cell.length)][Math.floor(Math.random() * this.cell[0].length)].fadeTo(o.duration, (Math.random() * o.maxOpacity));
			},
			
			wipe: function()
			{
				if(this.hi == undefined)		// init
				{
					this.hi = 0;
					this.left = false;
					this.xindexes = new Array(o.gridHeight);
				}
				
				
				for(var y=(o.gridHeight-1); y>0; y--)
				{
					(this.xindexes[y] = this.xindexes[y-1]);
				}
				
				this.xindexes[0] = (this.left ? this.hi : ((o.gridWidth-1) - this.hi));
				
				for(var y=0; y<o.gridHeight; y++)
				{
					(this.xindexes[y] != undefined) && this.cell[y][this.xindexes[y]].stop().css({opacity: o.maxOpacity}).fadeTo(o.duration, o.minOpacity);
				}
				if(++this.hi == o.gridWidth)
				{
					this.hi = 0;
					this.left = !this.left;
				}
			}
		}
		
		
		
		/*
			main jQuery plugin method
		*/
        return this.each(function() 
        {
			
        	//alert(this);
        	//var container = $('<div style="font-size:5px;width: 100px; height:30px"/>').appendTo(this).css(
        	var id = ("spinner" + Math.random()).replace('0.','');
        	/*
        	var container = $('<div id="' + id + '"/>').appendTo(this).css(
        	/*/
        	var padding = 0;	//parseInt($(this).css('padding-right')) + parseInt($(this).css('padding-right'));
        	var container = $(this).css(
        	//*/
																{
																	background: o.background,
																	//border: '1px solid #aae',
																	//padding: '1px',
																	//margin: 'auto',
																	//'font-size': o.rowHeight + 'px',
																	'font-size': '0px',
																	width: ((o.gridWidth * o.tileWidth) + padding) +'px'
																}
															).get(0);
			
												
			spinner = this.spinner = {};
															
			/*
        	var percentageWidth = Math.floor(100 / o.gridWidth);
        	/*/
        	//var percentageWidth = Math.ceil(100 / o.gridWidth);											// TODO: try calculating pixel widths
        	//*/
        	//(percentageWidth == 33) && (percentageWidth = 34);																						// if the percentage is 33 (o.gridWidth == 3) then fix it up		
        	
        	spinner.cell = new Array(o.gridHeight);
        	
        	for(var y=0; y<o.gridHeight; y++)
        	{
        		//var row = $('<div style="border:0px solid #999"></div>').appendTo(container);
        		var row = $('<div/>').appendTo(container);
        		spinner.cell[y] = new Array(o.gridWidth);
        		
				for(var x=0; x<o.gridWidth; x++)
				{
					var opacity = (Math.random() * o.maxOpacity);
					//container.cell[y][x] = $('<div style="' + (x==(o.gridWidth-1) ? "" : "float:right;") + 'background-color:#00f; width:' + percentageWidth + '%; height: ' + o.rowHeight + '; opacity:' + opacity + '">&nbsp;</div>').appendTo(row);
					spinner.cell[y][x] = initialisers[o.initialiser]($('<div style="' + (x==(o.gridWidth-1) ? "" : "float:right;") + 'width:' + o.tileWidth + 'px; height: ' + o.tileHeight + ';">&nbsp;</div>').appendTo(row));
				}
        	}

        	spinner.animator = animators[o.animator];
				
        	spinner.start = function()
        	{
        		if(!window[id])
        		{
					window[id] = spinner;									// create an easy reference to the spinner for conveniance
					
					spinner.spin = function()
					{
						//this.cell[Math.floor(Math.random() * this.cell.length)][Math.floor(Math.random() * this.cell[0].length)].fadeTo(400, (Math.random() * o.maxOpacity));
						this.animator();
						
						//*
						setTimeout('window.' + id + '.spin()', o.refreshRate);
						/*/
						setTimeout('window.' + id + '.spin()', 2000);
						//*/
					}
					spinner.spin();
				}
			}
        	
        	
        	spinner.stop = function()
        	{
        		/*
        		this.spin = $.noop;
        		window[id] = null;
        		/*/
        		this.spin = function()
        		{
					window[id] = null;
				}
        		//*/
        	}
        	
			window[id] = null;
        	o.dontStart || spinner.start();																								// if dontStart has not been set - start automatically
        });
    };
})(jQuery);
